﻿using System;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using DNT.RavenQA.Core.Extensions;
using DNT.RavenQA.Web.Infrastructure.Registry;
using Raven.Client;
using Raven.Client.Embedded;
using Raven.Client.Listeners;
using Rhino.Mocks;
using ControllerBase = DNT.RavenQA.Web.Controllers.ControllerBase;

namespace DNT.RavenQA.Web.Tests.Controllers
{
    public class ControllerTestBase : IDisposable
    {
        protected ControllerTestBase()
        {
            _documentStore = new EmbeddableDocumentStore { RunInMemory = true };
            DocumentConventionBuilder.SetConventions(_documentStore.Conventions);
            _documentStore.RegisterListener(new NoStaleQueriesAllowed());
            _documentStore.Initialize();
        }

        private class NoStaleQueriesAllowed : IDocumentQueryListener
        {
            public void BeforeQueryExecuted(IDocumentQueryCustomization queryCustomization)
            {
                queryCustomization.WaitForNonStaleResults();
            }
        }

        private readonly EmbeddableDocumentStore _documentStore;

        protected ControllerContext ControllerContext { get; set; }

        protected void ExecuteAction<TController>(Func<IDocumentSession, TController> builder,
                                                  Action<TController> action)
            where TController : ControllerBase
        {
            var session = _documentStore.OpenSession();
            var controller = builder(session);
            var httpContext = MockRepository.GenerateStub<HttpContextBase>();
            httpContext.Stub(x => x.Response).Return(MockRepository.GenerateStub<HttpResponseBase>());
            ControllerContext = new ControllerContext(httpContext, new RouteData(), controller);
            controller.ControllerContext = ControllerContext;
            action(controller);
            session.SaveChanges();
        }

        public void Dispose()
        {
            if (_documentStore.IsNotNull())
                _documentStore.Dispose();
        }
    }
}